package drds.data_propagate.parse.binlog_event_position_manager;

import drds.data_propagate.binlog_event.secondary.position.BinLogEventPosition;
import drds.data_propagate.parse.exception.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 实现基于failover查找的机制完成meta的操作
 *
 * <pre>
 * 应用场景：比如针对内存buffer，出现HA切换，先尝试从内存buffer区中找到lastest readedIndex，如果不存在才尝试找一下meta里消费的信息
 * </pre>
 */
public class FailbackBinLogEventPositionManager extends AbstractBinLogEventPositionManager {

    private final static Logger logger = LoggerFactory.getLogger(FailbackBinLogEventPositionManager.class);

    private final BinLogEventPositionManager primary;
    private final BinLogEventPositionManager secondary;

    public FailbackBinLogEventPositionManager(BinLogEventPositionManager primary, BinLogEventPositionManager secondary) {
        if (primary == null) {
            throw new NullPointerException("nul primary BinLogEventPositionManager");
        }
        if (secondary == null) {
            throw new NullPointerException("nul secondary BinLogEventPositionManager");
        }

        this.primary = primary;
        this.secondary = secondary;
    }

    @Override
    public void start() {
        super.start();

        if (!primary.isStart()) {
            primary.start();
        }

        if (!secondary.isStart()) {
            secondary.start();
        }
    }

    @Override
    public void stop() {
        super.stop();

        if (secondary.isStart()) {
            secondary.stop();
        }

        if (primary.isStart()) {
            primary.stop();
        }
    }

    @Override
    public BinLogEventPosition getLatestBinLogEventPosition(String taskId) {
        BinLogEventPosition binLogEventPosition = primary.getLatestBinLogEventPosition(taskId);
        if (binLogEventPosition != null) {
            return binLogEventPosition;
        }
        return secondary.getLatestBinLogEventPosition(taskId);
    }

    @Override
    public void persistBinLogEventPosition(String taskId, BinLogEventPosition binLogEventPosition) throws ParseException {
        try {
            primary.persistBinLogEventPosition(taskId, binLogEventPosition);
        } catch (ParseException e) {
            logger.warn(
                    "persistBinLogEventPosition use primary log readedIndex manager exception. taskIdSequense: {}, nextBinLogEventPosition: {}",
                    taskId, binLogEventPosition, e);
            secondary.persistBinLogEventPosition(taskId, binLogEventPosition);
        }
    }
}
